(function ( $ ) {
	var _stack = 0,
		_lastID = 0,
		_generateID = function () {
			_lastID ++;
			return 'tvd-materialize-lean-overlay-' + _lastID;
		};

	$.fn.extend( {
		openModal: function ( options ) {

			var $body = $( 'body' ).css( 'overflow', 'hidden' );

			var defaults = {
					opacity: 0.7,
					in_duration: 350,
					out_duration: 250,
					ready: undefined,
					complete: undefined,
					dismissible: true,
					starting_top: '4%',
					overlay_class: ''
				},
				overlayID = _generateID(),
				$modal = $( this ),
				$overlay = $( '<div class="tvd-lean-overlay"></div>' ),
				lStack = (++ _stack);
			// Store a reference of the overlay
			$overlay.attr( 'id', overlayID ).css( 'z-index', 10000 + lStack * 2 );
			$modal.data( 'tvd-overlay-id', overlayID ).css( 'z-index', 10000 + lStack * 2 + 1 );

			$body.append( $overlay );

			// Override defaults
			options = $.extend( defaults, options );

			$overlay.addClass( options.overlay_class );

			if ( options.dismissible ) {
				$overlay.click( function () {
					$modal.closeModal( options );
				} );
				// Return on ESC
				$( document ).on( 'keyup.leanModal' + overlayID, function ( e ) {
					if ( e.keyCode === 27 ) {   // ESC key
						$modal.closeModal( options );
					}
				} );
			}

			$modal.find( ".tvd-modal-close" ).on( 'click.close', function ( e ) {
				$modal.closeModal( options );
			} );

			$overlay.css( {display: "block", opacity: 0} );

			$modal.css( {
				display: "block",
				opacity: 0
			} );

			$overlay.velocity( {opacity: options.opacity}, {
				duration: options.in_duration,
				queue: false,
				ease: "easeOutCubic"
			} );
			$modal.data( 'tvd-associated-overlay', $overlay[0] );

			// Define Bottom Sheet animation
			if ( $modal.hasClass( 'bottom-sheet' ) ) {
				$modal.velocity( {bottom: "0", opacity: 1}, {
					duration: options.in_duration,
					queue: false,
					ease: "easeOutCubic",
					// Handle modal ready callback
					complete: function () {
						if ( typeof(options.ready) === "function" ) {
							options.ready();
						}
					}
				} );
			}
			else {
				$.Velocity.hook( $modal, "scaleX", 0.7 );
				$modal.css( {top: options.starting_top} );
				$modal.velocity( {top: "10%", opacity: 1, scaleX: '1'}, {
					duration: options.in_duration,
					queue: false,
					ease: "easeOutCubic",
					// Handle modal ready callback
					complete: function () {
						if ( typeof(options.ready) === "function" ) {
							options.ready();
						}
					}
				} );
			}


		}
	} );

	$.fn.extend( {
		closeModal: function ( options ) {
			var defaults = {
					out_duration: 250,
					complete: undefined
				},
				$modal = $( this ),
				overlayID = $modal.data( 'tvd-overlay-id' ),
				$overlay = $( '#' + overlayID );

			options = $.extend( defaults, options );

			// Disable scrolling
			$( 'body' ).css( 'overflow', '' );

			$modal.find( '.tvd-modal-close' ).off( 'click.close' );
			$( document ).off( 'keyup.leanModal' + overlayID );

			$overlay.velocity( {opacity: 0}, {
				duration: options.out_duration,
				queue: false,
				ease: "easeOutQuart"
			} );
			_stack --;

			// Define Bottom Sheet animation
			if ( $modal.hasClass( 'bottom-sheet' ) ) {
				$modal.velocity( {bottom: "-100%", opacity: 0}, {
					duration: options.out_duration,
					queue: false,
					ease: "easeOutCubic",
					// Handle modal ready callback
					complete: function () {
						$overlay.css( {display: "none"} );

						// Call complete callback
						if ( typeof(options.complete) === "function" ) {
							options.complete();
						}
						$overlay.remove();
					}
				} );
			}
			else {
				if ( options.out_duration === 0 ) {
					$modal.hide( 0 );
					if ( typeof(options.complete) === "function" ) {
						options.complete();
					}
					$overlay.remove();
					return;
				}
				$modal.velocity(
					{top: options.starting_top, opacity: 0, scaleX: 0.7}, {
						duration: options.out_duration,
						complete: function () {

							$( this ).css( 'display', 'none' );
							// Call complete callback
							if ( typeof(options.complete) === "function" ) {
								options.complete();
							}
							$overlay.remove();
						}
					}
				);
			}
		}
	} );

	$.fn.extend( {
		leanModal: function ( option ) {
			return this.each( function () {

				var defaults = {
						starting_top: '4%'
					},
					$this = $( this ),
				// Override defaults
					options = $.extend( defaults, option, $this.data() );

				// Close Handlers
				$this.click( function ( e ) {
					options.starting_top = ($( this ).offset().top - $( window ).scrollTop()) / 1.15;
					var modal_id = $this.attr( "href" ) || '#' + $this.data( 'target' );
					$( modal_id ).openModal( options );
					e.preventDefault();
					e.stopPropagation();
					return false;
				} ); // done set on click
			} ); // done return
		}
	} );
})( jQuery );
